package com.nulldev.util.net.proxy;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.nulldev.util.java.JVMUtil;

public class ProxyClientHeader {
	private String method;
    private String host;
    private int port;
    private boolean https;
    private byte[] bytes;
    private String url;

    private final InputStream in;
    private final ByteArrayOutputStream consumedBytes;

    private ProxyClientHeader(final InputStream in) {
        this.in = in;
        this.consumedBytes = new ByteArrayOutputStream();
    }

    public static ProxyClientHeader parseFrom(final InputStream in) throws IOException {
        final ProxyClientHeader header = new ProxyClientHeader(in);
        header.init();
        return header;
    }

    private void init() throws IOException {
    	final String l = readLine();
    	final String[] args = l.split(" ");
    	final String url = args[1];
        this.method = args[0]; // the first word is http method name
        this.https = this.method.equalsIgnoreCase("CONNECT"); // method CONNECT means https
        if (this.https) {
        	this.url = "https://" + url.split(":")[0];
        }else {
        	this.url = url;
        }
        if (this.url.endsWith("]")) {
        	this.url = this.url.substring(0, this.url.length() - 1);
        }
        for (String line = readLine(); line != null && !line.isEmpty(); line = readLine()) {
            if (line.startsWith("Host: ")) {
                String[] arr = line.split(":");
                this.host = arr[1].trim();
                try {
                    if (arr.length == 3) {
                        this.port = Integer.parseInt(arr[2]);
                    } else if (https) {
                        this.port = 443; // https
                    } else {
                        this.port = 80; // http
                    }
                } catch (NumberFormatException e) {
                    throw new IOException(e);
                }
            }
        }
        if (this.host == null || this.port == 0) {
            throw new IOException("cannot find header \'Host\'");
        }
        this.bytes = this.consumedBytes.toByteArray();
    }

    private String readLine() throws IOException {
        final StringBuilder builder = new StringBuilder();
        for (int b = in.read(); b != -1; b = in.read()) {
            this.consumedBytes.write(b);
            builder.append((char) b);
            int len = builder.length();
            if (len >= 2 && builder.substring(len - 2).equals("\r\n")) {
                builder.delete(len - 2, len);
                return builder.toString();
            }
        }
        return builder.length() == 0 ? null : builder.toString();
    }

	public String getHost() {
		return this.host;
	}

	public int getPort() {
		return this.port;
	}

	public boolean isHTTPS() {
		return this.https;
	}

	public byte[] getBytes() {
		return this.bytes;
	}
	
	@Override
	public String toString() {
		return "ProxyClient.Header[host=" + this.host + ",port=" + this.port + ",https=" + this.https + ",length=" + this.bytes.length + ","
				+ "url=" + this.url + "]";
	}

	public String getURL() {
		return this.url;
	}
}
